package trivia;


import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JRadioButton;
import javax.swing.JCheckBox;

import score.Scorelist;

import myExceptions.MyFileException;


public class TriviaFrame extends JFrame {

	private static final long serialVersionUID = 5853950115063242757L;
	
	private JFrame TriviaFrame = null;  
	private JPanel jTriviaFContentPane = null;
	private JMenuBar jJMenuBar = null;
	private JMenu jFileMenu = null;
	private JMenu jEdit = null;
	private JMenuItem jNewGameMenuItem = null;
	private JMenuItem jExitMenuItem = null;
	private JMenuItem jEditFileMenuItem = null;
	private JMenu jViewMenu = null;
	private JMenuItem jRankingsMenuItem = null;
	private ButtonGroup optionGroup = null;  
	private JRadioButton [] jOptionsRadioButton;
	private JCheckBox [] jOptionsCheckBox;
	private JButton jNextButton = null;
	private JTextPane jQuestionTextPane = null;
	private JTextField jAnsTextField = null;
	@SuppressWarnings("unused")
	private JLabel jQ = null;
	@SuppressWarnings("unused")
	private JRadioButton jOptionRadioButton = null;
	private JRadioButton jRadioButton = null;
	@SuppressWarnings("unused")
	private JCheckBox jCheckBox = null;
	private JButton jRestartButton = null; 

	private int cantCheckboxes = 0;
	private Scorelist l = null;
	private int actualScore = 0;
	private NewGameFrame gameFrame;
	private NewGame game;
	private int countQshown = 0;
	private FinishFrame finish = null;
	private ChooseLevelFrame jChooseLevel = null;
	private String diffic = null;
	private ScoreFrame rank;
	private EditFrame edit = null;
	
	private File file;
	@SuppressWarnings("unused")
	private ErrorFrame err;

	//constructor
	public TriviaFrame () {
		TriviaFrame = getTriviaFrame();
		getScoreList();	
	}
	
	private void getScoreList() {
		BufferedReader inStream = null;
		try {
			inStream = new BufferedReader(new FileReader("puntajes.txt"));
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
			
		try {
			l = new Scorelist( inStream );
		} catch (MyFileException e) {
			err = new ErrorFrame("Error in score file");
		}
	}
	
	/**
	 * This method initializes TriviaFrame	
	 * 	
	 * @return javax.swing.JFrame	
	 */
	public JFrame getTriviaFrame() {
		if (TriviaFrame == null) {
			TriviaFrame = new JFrame();
			TriviaFrame.setName("Trivia");
			TriviaFrame.setTitle("Trivia");
			TriviaFrame.setBounds(new Rectangle(320, 100, 468, 502));
			TriviaFrame.setJMenuBar(getJJMenuBar());
			TriviaFrame.setContentPane(getJContentPane());
			TriviaFrame.setVisible(true);
			gameFrame = getJGameFrame();
			
		}
		return TriviaFrame;
	}
	
	private EditFrame getJEditQFrame() {
		return edit = new EditFrame(game.getQ());
	}
	
	private NewGameFrame getJGameFrame () {
		
		if(gameFrame == null) {
			gameFrame = new NewGameFrame();			
			gameFrame.getJOkButton().addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					//instancia newgame
					
					if((file = searchFile()) != null) {
						try {
							game = new NewGame(file, diffic = (String)gameFrame.getJDifficComboBox().getSelectedItem());
							
							startGame();
							
							jViewMenu.setEnabled(true);
							jEdit.add(getJEditFileMenuItem());												
							jEdit.setEnabled(true);
						} catch (MyFileException exc) {
							// TODO Bloque catch generado automticamente
							err = new ErrorFrame(exc.getMessage());
							file = null;
						}
					}

					gameFrame.getJNewGameFrame().setVisible(false);

				}
			});
		}
		return gameFrame;
	}

	/**
	 * This method initializes jContentPane	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJContentPane() {
		if (jTriviaFContentPane == null) {
			jTriviaFContentPane = new JPanel();
			jTriviaFContentPane.setLayout(null);
		}
		return jTriviaFContentPane;
	}

	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJJMenuBar() {
		if (jJMenuBar == null) {
			jJMenuBar = new JMenuBar();
			jJMenuBar.add(getJFileMenu());
			jJMenuBar.add(getJViewMenu());
		}
		return jJMenuBar;
	}

	/**
	 * This method initializes jFileMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getJFileMenu() {
		if (jFileMenu == null) {
			jFileMenu = new JMenu();
			jFileMenu.setText("File");
			jFileMenu.add(getJNewGameMenuItem());
			jFileMenu.add(getJEditMenu());
			jFileMenu.add(getJExitMenuItem());
		}
		return jFileMenu;
	}

	private JMenu getJEditMenu() {
		if (jEdit == null) {
			jEdit = new JMenu();
			jEdit.setText("Edit");
			jEdit.setEnabled(false);
		}
		return jEdit;
	}

	/**
	 * This method initializes jNewGameMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getJNewGameMenuItem() {
		if (jNewGameMenuItem == null) {
			jNewGameMenuItem = new JMenuItem();
			jNewGameMenuItem.setText("New game");
			jNewGameMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					gameFrame.getJNewGameFrame().setVisible(true);
				}
			});
		}
		return jNewGameMenuItem;
	}

	/**
	 * This method initializes jExitMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getJExitMenuItem() {
		if (jExitMenuItem == null) {
			jExitMenuItem = new JMenuItem();
			jExitMenuItem.setText("Exit");
			jExitMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					BufferedWriter outScore = null, outQ = null;
					
					try {
						outScore = new BufferedWriter(new FileWriter("puntajes.txt"));
						outQ = new BufferedWriter(new FileWriter("preguntas.txt"));
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					try {
						l.saveFile(outScore);
						game.getQ().saveFile(outQ);
					} catch (IOException e1) {
						err = new ErrorFrame("Error saving file");
					} catch (MyFileException e2) {
						err = new ErrorFrame("Error saving file");
					}
					
					try {
						outScore.close();
						outQ.close();
						
					} catch (IOException e1) {
						err = new ErrorFrame("Error saving file");
					}
					
					System.exit(0);
				}
			});
		}
		return jExitMenuItem;
	}
	/**
	 * This method initializes EditFileMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getJEditFileMenuItem() {
		if (jEditFileMenuItem == null) {
			jEditFileMenuItem = new JMenuItem();
			jEditFileMenuItem.setText("Edit questionary");
			jEditFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					edit = getJEditQFrame();
					edit.getJChooseQFrame().setVisible(true);
				}
			});
		}
		return jEditFileMenuItem;
	}
	/**
	 * This method initializes jViewMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getJViewMenu() {
		if (jViewMenu == null) {
			jViewMenu = new JMenu();
			jViewMenu.setText("View");
			jViewMenu.setEnabled(false);
			jViewMenu.add(getJViewRankingsItem());
			
		}
		return jViewMenu;
	}
	
	private JMenuItem getJViewRankingsItem() {
		if (jRankingsMenuItem== null) {
			jRankingsMenuItem = new JMenuItem();
			jRankingsMenuItem.setText("Rankings");
			jRankingsMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					rank = new ScoreFrame( l, diffic );
					rank.getJScoreFrame().setVisible(true);
				}
			});
		}
		return jRankingsMenuItem;
	}
	
	protected void startGame () {
		TriviaFrame.setContentPane(getJNewContentPane());
		TriviaFrame.getRootPane().setDefaultButton(jNextButton);
		TriviaFrame.setVisible(true);
	}
	
	private JPanel getJNewContentPane () {
		jTriviaFContentPane = new JPanel();
		jTriviaFContentPane.setLayout(null);
		jTriviaFContentPane.add(jQ = getJLabel(15, 17, 94, 17, "Q "+(countQshown+1)));
		jTriviaFContentPane.add(getJQuestionTextPane());
		getAnswersOptions();
		jTriviaFContentPane.add(jNextButton = getJNextButton());
		jTriviaFContentPane.add(jRestartButton = getJRestartButton());
		return jTriviaFContentPane;
	}
	
	private void getAnswersOptions () {
		
		switch (game.getQ().getType(countQshown)) {
			case 1:
				jTriviaFContentPane.add(getJAnsTextField());
				jTriviaFContentPane.add(getJLabel(38, 210, 52, 31, "Answer: "));				
				break;
			
			case 2:
				//TODO
				// va un textfield
				jTriviaFContentPane.add(getJAnsTextField());
				jTriviaFContentPane.add(getJLabel(38, 210, 52, 31, "Answer: "));
				break;
			
			case 3:
	//			TODO
				//multiplechoice con una respuesta
				addJRadioButtonsToJPane();

				break;
				
			case 4:
	//			TODO
				//checkbox
				addJCheckBoxToJPane();
				break;
				
			case 5:
	//			TODO
				//multiplechoise true/false
				addJRadioButtonsToJPane();
				break;
			}
	}
	
	
	private void addJCheckBoxToJPane() {
		int countOptions = game.getQ().getOptionsCount(countQshown);
		jOptionsCheckBox = getJCheckBoxes(countOptions);
	}
	
	private JCheckBox [] getJCheckBoxes (int n) {
		jOptionsCheckBox = new JCheckBox [n];
		String op;
		int i = 0;
		int y;
		for ( i = 0, y = 170; i < n; i++, y += 30) {
			op = game.getQ().getOptions(countQshown)[i];
			jOptionsCheckBox[i] = getJCheckBox (15, y, 200, 30, op);
			jOptionsCheckBox[i].setText(game.getQ().getOptions(countQshown)[i]);
			jTriviaFContentPane.add(jOptionsCheckBox[i]);
		}
		cantCheckboxes = i;
		
		return jOptionsCheckBox;
	}
	
	private JCheckBox getJCheckBox(int x, int y, int w, int h, String text) {
		JCheckBox checkBox = new JCheckBox();
		checkBox.setBounds(x, y, w, h);
		checkBox.setText(text);
		return checkBox;
	}
	
	private void addJRadioButtonsToJPane() {
		int countOptions = game.getQ().getOptionsCount(countQshown);
		jOptionsRadioButton = getJRadioButtons(countOptions);
		optionGroup =  new ButtonGroup();
		for (int i=0; i < countOptions; i++) {
			optionGroup.add(jOptionsRadioButton[i]);
		}
	}
	
	private JRadioButton[] getJRadioButtons(int n) {
		jOptionsRadioButton = new JRadioButton [n];
		String op;
		
		for (int i = 0, y = 170; i < n; i++, y += 30) {
			op = game.getQ().getOptions(countQshown)[i];
			jOptionsRadioButton[i] = getJRadioButton(15, y, 106, 30, op);
			jOptionsRadioButton[i].setText(game.getQ().getOptions(countQshown)[i]);
			jTriviaFContentPane.add(jOptionsRadioButton[i]);
		}
		
		return jOptionsRadioButton;
	}
	private JRadioButton getJRadioButton(int i, int j, int k, int l, String op) {
		jRadioButton = new JRadioButton();
		jRadioButton.setBounds(new Rectangle(i, j, k, l));
		jRadioButton.setText(op);
		return jRadioButton;
	}	
	private JLabel getJLabel(int x, int y, int w, int h, String text) {
		JLabel label = new JLabel(text);
		label.setBounds(new Rectangle(x, y, w, h));
		label.setText(text);
		return label;
	}
	
	/**
	 * This method initializes jNextButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJNextButton() {
		if (jNextButton == null) {
			jNextButton = new JButton();
			jNextButton.setBounds(new Rectangle(251, 210, 94, 34));
			jNextButton.setText("Next");
			jNextButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
					//TODO debug
					
					switch (game.getQ().getType(countQshown)) {
					case 1:
						String s = jAnsTextField.getText();
						System.out.println(" texto " + s );
						if (game.getQ().isCorrect(countQshown, s)) {
							actualScore += game.getQ().getScores(countQshown);
							System.out.println( "sumo: " + game.getQ().getScores(countQshown));
						}
						jAnsTextField.setText("");
						break;
						
					case 2:
						//TODO
						// va un textfield
						String p = jAnsTextField.getText();
						System.out.println(" texto " + p );
						if (game.getQ().isCorrect(countQshown, p)) {
							actualScore += game.getQ().getScores(countQshown);
							System.out.println( "sumo: " + game.getQ().getScores(countQshown));
						}
						jAnsTextField.setText("");
						break;
					
					case 3:
			//			TODO
						//multiplechoice con una respuesta
						String n = null;
						int index = optionGroup.getButtonCount();
						for( int i = 0; i < index; i++ ){
							if( jOptionsRadioButton[i].isSelected() ){
								n = jOptionsRadioButton[i].getText();
								System.out.println("elegi opcion " + i + " texto " + n );
								if( game.getQ().isCorrect(countQshown, n )){
									System.out.println("sumo  "+ game.getQ().getScores(countQshown));
									actualScore += game.getQ().getScores(countQshown);
								}
							}
						}
						if( n == null ){
							jOptionsRadioButton[0].setSelected(true);
						}
						
						
						break;
						
					case 4:
			//			TODO
						//checkbox
					
						String[] answ = new String[cantCheckboxes];
						int answsize = 0;
						for( int i = 0, j = 0; i < cantCheckboxes; i++ ) {
							if( jOptionsCheckBox[i].isSelected() ){
								answ[j] = jOptionsCheckBox[i].getText();
								answsize++;
								System.out.println("elegi opcion " + i + " texto " + answ[j] );
								j++;
							}
						}
						if ( game.getQ().isCorrect(countQshown, answ, answsize) ){
							System.out.println( "sumo: " + game.getQ().getScores(countQshown));
							actualScore += game.getQ().getScores(countQshown);
						
						}
						break;
						
					case 5:
			//			TODO
						//multiplechoise true/false
						String c = null;
						for( int i = 0; i < 2; i++ ){
							if( jOptionsRadioButton[i].isSelected() ){
								c = jOptionsRadioButton[i].getText();
								System.out.println("elegi opcion " + i + " " + c );
								if( game.getQ().isCorrect(countQshown, c )){
									actualScore += game.getQ().getScores(countQshown);
									System.out.println( "sumo: " + game.getQ().getScores(countQshown));
								}
							}
						}
						break;
					}
 
					if (game.getQ().getCountQ() == (countQshown+1)) {
						
						double points = ((double)actualScore / game.getQ().getTotalScore())*100;
						l.newScore(gameFrame.getJNameTextField().getText(), points, diffic);
						finish = new FinishFrame ();
						finish.setName(gameFrame.getJNameTextField().getText());
						finish.setScore(Double.toString( (double)actualScore / game.getQ().getTotalScore()*100));
						jNextButton.setEnabled(false);
						finish.getJFinishFrame().setVisible(true);
						
						finish.getJExitButton().addActionListener(new java.awt.event.ActionListener() {
							public void actionPerformed(java.awt.event.ActionEvent e) {
								//TODO GUARDAR LOS PUNTAJES AL ARCHIVO
								saveToFile(l, "puntajes.txt");
								System.exit(0);
							}
						});
						
						
					} else {
						countQshown += 1;
						startGame();
						}
					}
				});
			}
		return jNextButton;
	}
	
	private void saveToFile (Scorelist list, String fileName) {
		BufferedWriter outStream = null;	
		try {
			outStream = new BufferedWriter(new FileWriter(fileName));
		} catch (IOException e1) {
			err = new ErrorFrame("Error saving "+fileName);
		}
		
		try {
		list.saveFile(outStream);
		} catch (IOException e1) {
			err = new ErrorFrame("Error saving "+fileName);
		}
		
		try {
			outStream.close();
		} catch (IOException e1) {
			err = new ErrorFrame("Error saving "+fileName);
		}
		
	}
	
	/**
	 * This method initializes jTextPane	
	 * 	
	 * @return javax.swing.JTextPane	
	 */
	private JTextPane getJQuestionTextPane() {
			jQuestionTextPane = new JTextPane();
			jQuestionTextPane.setBounds(new Rectangle(14, 40, 319, 122));
			jQuestionTextPane.setText(game.getQ().getQuestion(countQshown));
		return jQuestionTextPane;
	}
	
	/**
	 * This method initializes jAnsTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJAnsTextField() {
		if (jAnsTextField == null) {
			jAnsTextField = new JTextField();
			jAnsTextField.setBounds(new Rectangle(90, 210, 136, 31));
		}
		return jAnsTextField;
	}
	
	/**
	 * This method initializes jRestartButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJRestartButton() {
		if (jRestartButton == null) {
			jRestartButton = new JButton();
			jRestartButton.setText("Restart");
			jRestartButton.setBounds(new Rectangle(358, 210, 90, 25));
			jRestartButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					jNextButton.setEnabled(true);
					actualScore = 0;
					game.getQ().setTotalScore(0);
					jChooseLevel = new ChooseLevelFrame();
					jChooseLevel.getJOkButton().addActionListener(new java.awt.event.ActionListener() {
						public void actionPerformed(java.awt.event.ActionEvent e) {
							
							if(jChooseLevel.isEasySelected()) {
								System.out.println("seleccione el easy");
								game.getQ().setRandomQ("Easy");
								
							}
							else if (jChooseLevel.isNormalSelected()) {
								game.getQ().setRandomQ("Normal");
								System.out.println("seleccione el Normal");
							}
							else {
								if (jChooseLevel.isHardSelected()) {
									game.getQ().setRandomQ("Hard");
									System.out.println("seleccione el Hard");
								}
							}
							
							countQshown = 0;
							startGame();

							//game.getQ().setRandomQ()
							System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
							jChooseLevel.getJChooseLFrame().setVisible(false);
						
						}
					});
					
				}
			});
		}
		//game.getQ().showPlayQ();
		return jRestartButton;
	}
	/**
	 * seleccionador de archivos
	 * @return devuelve una variable de tipo File que apunta al archivo elegido
	 */
	private File searchFile () {
		File f = null;
		JFileChooser fileopen = new JFileChooser();
		
		int ret = fileopen.showDialog(gameFrame.getJNewGameContentPane(), "Open file...");
		if (ret == JFileChooser.APPROVE_OPTION) {
			f = fileopen.getSelectedFile();
		}
		return f;
	}
}